﻿using Abp.Authorization;
using Abp.Linq.Expressions;
using Abp.Runtime.Session;
using Abp.UI;
using Basefr.App;
using Basefr.App.Helper;
using Basefr.Consts;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Paas.App.Interface.Meta;
using Paas.App.Interface.Meta.Dtos;
using Paas.App.Interface.Meta.Messages;
using Paas.Core;
using Paas.Core.Const.Enums;
using Paas.Core.Meta.Entities;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Threading.Tasks;

namespace Paas.App.Meta
{
    [Route("meta-application")]

    [AbpAuthorize()]
    public class ApplicationAppService : AppService, IApplicationAppService
    {
        /// <summary>
        /// 数据库帮助类
        /// </summary>
        private readonly SqlHelper _sqlHelper;
        private readonly IMainRepository<Application> _applicationRepo;


        public ApplicationAppService(IConfiguration configuration, IMainRepository<Application> applicationRepo)
        {
            _sqlHelper= new SqlHelper(configuration[ConnectionStringNames.Customer]);
            _applicationRepo = applicationRepo;
        }

        #region 增改
        [HttpPost(nameof(SaveApplication))]
        public async Task<SaveApplicationOutput> SaveApplication(SaveApplicationInput input)
        {
            if (input == null) throw new UserFriendlyException("保存应用信息失败：input为空！");
            if (input.Item?.Id != 0)
            {
                var uData = await _applicationRepo.GetAsync(input.Item.Id);
                if (uData == null) throw new UserFriendlyException("未找到需要更新的对象！");

                if (uData.CurrentStatus==MetaStatus.New)
                {
                    uData.Name = input.Item.Name;//发布后此字段不能再编辑
                }
                uData.Label = input.Item.Label;
                uData.Description = input.Item.Description;

                await _applicationRepo.UpdateAsync(uData);
                return new SaveApplicationOutput();
            }

            var entity = ObjectMapper.Map<Application>(input.Item);
            //新增数据默认状态=新建
            entity.CurrentStatus = MetaStatus.New;

            await _applicationRepo.InsertAsync(entity);
            return new SaveApplicationOutput();
        }

        /// <summary>
        /// 发布
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        [HttpPost(nameof(PublicApplication))]
        public async Task PublicApplication(PublicApplicationInput input)
        {
            if (input!=null)
            {
                var uData = await _applicationRepo.FirstOrDefaultAsync(input.Id);
                if (uData == null) throw new UserFriendlyException("未找到需要更新的对象！");
                //首次发布时，创建数据库
                if (uData.CurrentStatus==MetaStatus.New)
                {
                    // 创建数据库
                    _sqlHelper.CreateDatabase(uData.Name);

                    uData.CurrentStatus = MetaStatus.Released;
                    await _applicationRepo.UpdateAsync(uData);
                }
            }
        }

        #endregion

        #region 查
        [HttpPost(nameof(SearchApplication))]
        public async Task<SearchApplicationOutput> SearchApplication(SearchApplicationInput input)
        {
            Expression<Func<Application, bool>> predicate = p => true;
            if (!string.IsNullOrWhiteSpace(input.Name))
            {
                var name = input.Name.Trim();
                predicate = predicate.And(p => p.Name.Contains(name));
            }
            if (input.Id!=null&& input.Id != 0)
            {
                predicate = predicate.And(p => p.Id == input.Id);
            }
            if (!string.IsNullOrWhiteSpace(input.Label))
            {
                predicate = predicate.And(p => p.Label.Contains(input.Label.Trim()));
            }
            if (input.CurrentStatus!=null&& input.CurrentStatus != 0)
            {
                predicate = predicate.And(p => p.CurrentStatus == input.CurrentStatus);
            }

            var result = await _applicationRepo.GetAllListAsync(predicate);
            var res = result.OrderByDescending(p => p.SortNum).Skip(input.SkipCount).Take(input.MaxResultCount).ToList();
            var totalCount = result.Count();
            var resultItems = ObjectMapper.Map<List<ApplicationDto>>(res);
            return new SearchApplicationOutput { Items = resultItems, TotalCount = totalCount };
        }

        [HttpPost(nameof(SearchAvailableApplication))]
        public async Task<SearchApplicationOutput> SearchAvailableApplication(SearchAvailableApplicationInput input)
        {
            Expression<Func<Application, bool>> predicate = p => true;
            if (!string.IsNullOrWhiteSpace(input.Name))
            {
                var name = input.Name.Trim();
                predicate = predicate.And(p => p.Name.Contains(name));
            }

            var result = await _applicationRepo.GetAllListAsync(predicate);
            var totalCount = result.Count();
            var resultItems = ObjectMapper.Map<List<ApplicationDto>>(result);
            return new SearchApplicationOutput { Items = resultItems, TotalCount = totalCount };
        }
        #endregion

        #region 删
        [HttpPost(nameof(DeleteApplication))]
        public async Task<DeleteApplicationOutput> DeleteApplication(DeleteApplicationInput input)
        {
            //await _applicationRepo.
            await _applicationRepo.DeleteAsync(input.Id);
            return new DeleteApplicationOutput();
        }
        #endregion
    }
}
